<template>
  <div class="ConfigForm">
    <el-form v-if="visible" :model="modelValue" label-position="top" ref="mainRef" v-bind="config.formProps">
      <el-row :gutter="20" v-bind="config.rowProps">
        <template v-for="(item, index) in config.columns" :key="(item.prop || '_') + '_' + index">
          <el-col v-if="!item.prop && item.columns">
            <h4 class="group-title" v-if="item.label">{{ item.label }}</h4>
            <hr v-if="item.label" />
            <el-row :gutter="20" v-if="item.columns && item.columns.length">
              <FormItem v-for="(item2, index2) in item.columns" :key="(item2.prop!) + index2" :item="item2"
                v-model="(modelValue!)[(item2.prop!)]" @update:model-value="valueChange($event, (item2.prop!))"
                :mode="config.mode" />
            </el-row>
          </el-col>
          <FormItem v-else :item="item" v-model="(modelValue!)[item.prop || '_']"
            @update:model-value="valueChange($event, item.prop || '_')" :mode="config.mode" />
        </template>
      </el-row>
    </el-form>
  </div>
</template>
<script lang="ts" setup>
import FormItem from './item.vue'
import { ref, nextTick } from 'vue'
import type { Config, Column } from './type'
import { ElForm, ElRow, ElCol } from 'element-plus'

interface Props {
  modelValue: ObjectAny // 绑定对象
  config: Config // 组件配置
}
const props = withDefaults(defineProps<Props>(), {})

let visible = ref(true)
const reRender = () => {
  visible.value = false
  nextTick(() => {
    visible.value = true
  });
}

const emit = defineEmits<{
  (e: 'update:modelValue', value: any): void
}>()

const valueChange = (value: any, prop: string) => {
  emit('update:modelValue', Object.assign(props.modelValue, { [prop]: value }))
}

// 设置默认值
const setDefaultValue = () => {
  let defaultValueData = JSON.parse(JSON.stringify(props.modelValue));
  const assignmentFun = (item: Column) => {
    if ((defaultValueData[(item.prop as string)] === undefined
      || defaultValueData[item.prop as string] === null
      || defaultValueData[item.prop as string] === ''
      || (Array.isArray(defaultValueData[item.prop as string]) && defaultValueData[item.prop as string].length === 0))
      && item.value !== undefined) {
      defaultValueData[item.prop as string] = item.value
    }
  }
  props.config.columns.forEach(item => {
    if (!item.prop) { // 如果没有给column写prop
      if (item.columns) { // 如果它嵌套了columns
        item.columns.forEach((item2: Column) => assignmentFun(item2))
      } else {

      }
    }
    else assignmentFun(item)
  });
  emit('update:modelValue', Object.assign(props.modelValue, defaultValueData))
}
setDefaultValue()

/**表单Ref */
const mainRef = ref()

defineExpose({ mainRef, reRender, setDefaultValue })
</script>
<style scope lang="scss">
.group-title {
  margin-bottom: 5px;
}
</style>